package cn.wdm.basic.interceptor;

import cn.wdm.basic.annotation.PreAuthorize;
import cn.wdm.basic.util.jwt.JwtUtils;
import cn.wdm.basic.util.jwt.Payload;
import cn.wdm.basic.util.jwt.RsaUtils;
import cn.wdm.basic.util.jwt.loginResult;
import cn.wdm.system.mapper.PermissionMapper;
import cn.wdm.user.domain.Logininfo;
import cn.wdm.user.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.security.PublicKey;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 *写拦截器 登录拦截器 二次请求的时候 在登陆的时候判断是否有过登录
 */
@Component //将当前类注入到spring容器中
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private PermissionMapper permissionMapper;
    /**
     *重写拦截方法
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //设置返回vue界面的的格式为json格式
        response.setContentType("application/json;charset=utf-8");
        //编码集为utf-8
        response.setCharacterEncoding("utf-8");
        //1.从请求头中获取token 这里的token是前端 axios前置拦截器加的。
        //前端浏览器中的token是30分钟的，如果在这里拿不到说明浏览其中没有token或者是过期 前端的token是在登陆成功的时候设置的
        //登陆成功返回的ajaxresult map集合 里面有token和当前登录对象 logininfo
        String token = request.getHeader("U-TOKEN");//这里的token是jwt字符串
        //2.token不为空 登录过了  刷新过期时间 然后放行
        if (token != null) {
            //如果token不为空说明登陆过
            //1.解密token 获取公钥，然后解密
            PublicKey publicKey = RsaUtils.getPublicKey(JwtUtils.class.getClassLoader().getResource("hrm_auth_rsa.public").getFile());
            Payload<loginResult> payload = JwtUtils.getInfoFromToken(token, publicKey, loginResult.class);
            loginResult loginResult = payload.getUserInfo();
            //2.
            if (loginResult!=null) {
                Logininfo logininfo = loginResult.getLogininfo();
                //如果token不为空，说明登陆过，登陆成功，就要校验当前操作人的权限
                //1.判断当前操作人是员工还是用户 员工校验权限
                if(logininfo.getType()==0){
                    //2.拿到当前的请求路径 permission的controller的路径
                    //2.1从当前handler获取方法
                    HandlerMethod method = (HandlerMethod) handler;
                    PreAuthorize methodAnnotation = method.getMethodAnnotation(PreAuthorize.class);
                    if (methodAnnotation!=null) {
                        String currentLogininfoPermissionSn = methodAnnotation.value();
                        //3.拿到当前员工所拥有的权限
                        List<String> permissions = loginResult.getPermissions();
                        if(!permissions.contains(currentLogininfoPermissionSn)){
                            PrintWriter writer = response.getWriter();
                            writer.write("{\"success\":false,\"message\":\"noPermission\"}");
                            writer.flush();
                            writer.close();
                            return false;//阻止放行
                        }
                    }
                }
                //放行
                return true;
            }
            //根据U-TOKEN从redis中获取登录信息
           /* Object loginTmp = redisTemplate.opsForValue().get(token);
            if (loginTmp!=null) {
                Logininfo logininfo = (Logininfo) loginTmp;
                //如果token不为空，说明登陆过，登陆成功，就要校验当前操作人的权限
                //1.判断当前操作人是员工还是用户 员工校验权限
                if(logininfo.getType()==0){
                    //2.拿到当前的请求路径 permission的controller的路径
                    //2.1从当前handler获取方法
                    HandlerMethod method = (HandlerMethod) handler;
                    PreAuthorize methodAnnotation = method.getMethodAnnotation(PreAuthorize.class);
                    if (methodAnnotation!=null) {
                        String currentLogininfoPermissionSn = methodAnnotation.value();
                        //3.拿到当前员工所拥有的权限
                        System.out.println(logininfo.getId());
                        List<String> permissions=permissionMapper.findPermissionsByLogininfoId(logininfo.getId());
                        if(!permissions.contains(currentLogininfoPermissionSn)){
                            PrintWriter writer = response.getWriter();
                            writer.write("{\"success\":false,\"message\":\"noPermission\"}");
                            writer.flush();
                            writer.close();
                            return false;//阻止放行
                        }
                    }
                }
                redisTemplate.opsForValue().set(token,loginTmp,30, TimeUnit.MINUTES);
                //放行
                return true;
            }*/
        }
        //，否则未登录，重响应中获取输出流
        PrintWriter writer = response.getWriter();
        writer.write("{\"success\":false,\"message\":\"noLogin\"}");
        writer.flush();
        writer.close();
        return false;//阻止放行
    }
}
